
package com.hlkj.pay.controller.merchant;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.io.ByteArrayOutputStream;
import java.util.Collections;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.pay.app.common.IUploadService;
import com.hlkj.pay.app.common.impl.DownloadExcelServiceImpl;
import com.hlkj.pay.app.merchant.IMerchantAccessAppService;
import com.hlkj.pay.app.merchant.impl.MerchantAccessStatusProcessHandler;
import com.hlkj.pay.app.transfer.MerchantAccessDoToResp;
import com.hlkj.pay.controller.BaseController;
import com.hlkj.pay.dto.merchant.MerchantAccessInfoPageDto;
import com.hlkj.pay.dto.merchant.MerchantAccessInfoPageQueryDto;
import com.hlkj.pay.dto.merchant.MerchantWechatConfigDto;
import com.hlkj.pay.dto.merchant.access.MerchantAccessConsumerDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessAuthDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.service.merchant.IMerchantAccessService;
import com.hlkj.pay.vo.common.req.DeleteIdReq;
import com.hlkj.pay.vo.merchant.req.access.*;
import com.hlkj.pay.vo.merchant.resp.access.MerchantAccessAuthDetailResp;
import com.hlkj.pay.vo.merchant.resp.access.MerchantAccessAuthResp;
import com.hlkj.pay.vo.merchant.resp.access.MerchantAccessInfoListResp;
import com.hlkj.pay.vo.merchant.resp.access.MerchantAccessResp;
import com.hlkj.pay.vo.order.req.MerchantAuthExportInfo;
import com.hlkj.pay.vo.order.req.MerchantAuthExportReq;
import com.hlkj.pay.vo.order.req.MerchantChannelSplitReq;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

/**
 * @author HlpayTeam
 * @date 2024/09/12 11:32
 */
@Tag(name = "商户进件")
@RestController
@RequestMapping("/v1/merchant/access")
@RequiredArgsConstructor
public class MerchantAccessController extends BaseController {

    private final IMerchantAccessAppService merchantAccessAppService;

    private final IMerchantAccessService merchantAccessService;

    private final MerchantAccessStatusProcessHandler merchantAccessStatusProcessHandler;

    private final IUploadService uploadService;

    @Operation(summary = "进件保存草稿")
    @PostMapping("/save")
    CommonResult<Long> saveAccess(@RequestBody MerchantAccessReq merchantAccessReq) {
        if (merchantAccessReq.getId() == null)
            merchantAccessReq.setSourceFrom(MerchantEnum.SOURCE_FROM.LURU.getCode());
        return merchantAccessAppService.saveAccess(merchantAccessReq);
    }

    @Operation(summary = "商户进件提交")
    @PostMapping("/submit")
    CommonResult<Long> submitAccess(@RequestBody MerchantAccessReq merchantAccessReq) {
        // 前端提交的默认数据校验处理
        MerchantAccessInfoReq merchantAccessInfo = merchantAccessReq.getMerchantAccessInfo();
        Integer type = merchantAccessInfo.getType();
        Integer contactType = merchantAccessInfo.getContactType();
        Integer controllerType = merchantAccessInfo.getControllerType();
        if (MerchantEnum.MERCHANT_TYPE.PERSONAL.getCode().equals(type)) {
            merchantAccessInfo.setMerchantAccessLicense(null);
        }
        if (CommonEnum.YES_NO_TYPE.YES.getCode().equals(contactType)) {
            merchantAccessInfo.setMerchantAccessContact(null);
        }
        if (CommonEnum.YES_NO_TYPE.YES.getCode().equals(controllerType)) {
            merchantAccessInfo.setMerchantAccessController(null);
        }
        if (merchantAccessReq.getId() == null)
            merchantAccessReq.setSourceFrom(MerchantEnum.SOURCE_FROM.LURU.getCode());
        return merchantAccessAppService.submitAccess(merchantAccessReq);
    }

    @Operation(summary = "复制商户进件")
    @PostMapping("/copy")
    CommonResult<Long> copyAccess(@RequestBody MerchantAccessCopyReq merchantAccessCopyReq) {

        MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(merchantAccessCopyReq.getId());
        if(merchantAccessInfoDO == null){
            return CommonResult.error(0,"进件数据不存在");
        }
        // 相同渠道 状态已提交  不同渠道 则草稿
        MerchantEnum.ACCESS_STATUS status = MerchantEnum.ACCESS_STATUS.DRAFT;
        if(merchantAccessCopyReq.getChannelCode().equals(merchantAccessInfoDO.getChannelCode())){
            status = MerchantEnum.ACCESS_STATUS.SUBMIT;
        }
        // 一次
        if(merchantAccessCopyReq.getNum() == null || merchantAccessCopyReq.getNum() == 0 || merchantAccessCopyReq.getNum() == 1){
            CommonResult<MerchantAccessResp> merchantAccessRespCommonResult = merchantAccessAppService.merchantAccessInfo(merchantAccessCopyReq.getId());
            MerchantAccessResp data = merchantAccessRespCommonResult.getData();
            MerchantAccessReq merchantAccessReq = BeanUtil.copyProperties(data, MerchantAccessReq.class);
            merchantAccessReq.setId(null);
            merchantAccessReq.setChannelCode(merchantAccessCopyReq.getChannelCode());
            merchantAccessReq.setProviderCode(merchantAccessCopyReq.getProviderCode());
            merchantAccessReq.getMerchantAccessBusiness().setWechatMcc(null);
            merchantAccessReq.getMerchantAccessBusiness().setAlipayMcc(null);
            // 移除字典
            // MerchantAccessCardReq merchantAccessCard = merchantAccessReq.getMerchantAccessCard();
            // if (merchantAccessCard != null) {
            //     merchantAccessCard.setProvinceCode("");
            //     merchantAccessCard.setCityCode("");
            //     merchantAccessCard.setAreaCode("");
            // }
            // MerchantAccessBusinessReq merchantAccessBusiness = merchantAccessReq.getMerchantAccessBusiness();
            // if (merchantAccessBusiness != null) {
            //     merchantAccessBusiness.setProvinceCode("");
            //     merchantAccessBusiness.setCityCode("");
            //     merchantAccessBusiness.setAreaCode("");
            // }
            // MerchantAccessInfoReq merchantAccessInfo = merchantAccessReq.getMerchantAccessInfo();
            // if (merchantAccessInfo != null) {
            //     MerchantAccessLicenseReq merchantAccessLicense = merchantAccessInfo.getMerchantAccessLicense();
            //     if (merchantAccessLicense != null) {
            //         merchantAccessLicense.setProvinceCode("");
            //         merchantAccessLicense.setCityCode("");
            //         merchantAccessLicense.setAreaCode("");
            //     }
            // }
            merchantAccessReq.setSourceFrom(MerchantEnum.SOURCE_FROM.COPY.getCode());
            merchantAccessReq.setStatus(status);
            return merchantAccessAppService.saveAccess(merchantAccessReq);
        }else{
            for(int i=0; i< merchantAccessCopyReq.getNum(); i++){
                CommonResult<MerchantAccessResp> merchantAccessRespCommonResult = merchantAccessAppService.merchantAccessInfo(merchantAccessCopyReq.getId());
                MerchantAccessResp data = merchantAccessRespCommonResult.getData();
                MerchantAccessReq merchantAccessReq = BeanUtil.copyProperties(data, MerchantAccessReq.class);
                merchantAccessReq.setId(null);
                merchantAccessReq.setChannelCode(merchantAccessCopyReq.getChannelCode());
                merchantAccessReq.setProviderCode(merchantAccessCopyReq.getProviderCode());
                merchantAccessReq.getMerchantAccessBusiness().setWechatMcc(null);
                merchantAccessReq.getMerchantAccessBusiness().setAlipayMcc(null);
                merchantAccessReq.setSourceFrom(MerchantEnum.SOURCE_FROM.COPY.getCode());
                merchantAccessReq.setStatus(status);
                merchantAccessAppService.saveAccess(merchantAccessReq);
            }
        }
        return CommonResult.success();
    }

    @Operation(summary = "商户进件详情")
    @GetMapping("/detail")
    CommonResult<MerchantAccessResp> merchantAccessInfo(@RequestParam("id") Long id) {
        CommonResult<MerchantAccessResp> merchantAccessRespCommonResult = merchantAccessAppService.merchantAccessInfo(id);
        merchantAccessStatusProcessHandler.processAccess(id);
        return merchantAccessRespCommonResult;
    }

    @Operation(summary = "状态重跑 补偿接口 前端不用关注")
    @GetMapping("/process")
    CommonResult<Void> processAccessMessage(@RequestParam("id") Long id, @RequestParam("merchantAccessQuestType") Integer merchantAccessQuestType) {
        MerchantAccessConsumerDto merchantAccessConsumerDto = new MerchantAccessConsumerDto();
        merchantAccessConsumerDto.setAccessId(id);
        merchantAccessStatusProcessHandler.processAccess(merchantAccessConsumerDto, merchantAccessQuestType);
        return CommonResult.success();
    }

    @Operation(summary = "商户进件审核")
    @PostMapping("/approve")
    CommonResult<Void> merchantAccessInfo(@Validated @RequestBody MerchantAccessApproveReq merchantAccessApproveReq) {
        return merchantAccessAppService.platApprove(merchantAccessApproveReq);
    }

    @Operation(summary = "商户进件删除")
    @DeleteMapping("")
    CommonResult<Void> merchantAccessInfo(@Validated @RequestBody DeleteIdReq deleteIdReq) {
        return merchantAccessAppService.delete(deleteIdReq.getId());
    }

    @Operation(summary = "商户进件分配应用")
    @PostMapping("/channel")
    CommonResult<Void> merchantAccessChannel(@Validated @RequestBody MerchantAccessChannelReq merchantAccessChannelReq) {
        return merchantAccessAppService.accessChannel(merchantAccessChannelReq);
    }

    @Operation(summary = "安全发余额充值")
    @PostMapping("/recharge")
    CommonResult<String> merchantAccessRecharge(@Validated @RequestBody MerchantAccessRechargeReq merchantAccessRechargeReq) {
        return merchantAccessAppService.merchantAccessRecharge(merchantAccessRechargeReq);
    }

    @Operation(summary = "功能配置")
    @GetMapping("/auth")
    CommonResult<MerchantAccessAuthResp> merchantAccessChannel(@RequestParam("id") Long id) {
        return merchantAccessAppService.queryMerchantAccessAuth(id);
    }

    @Operation(summary = "更新功能配置开关状态")
    @PostMapping("/auth/state")
    CommonResult<Void> updateStatus(@Validated @RequestBody UpdateMerchantAccessAuthStateReq updateStatusReq) {
        return merchantAccessAppService.updateAccessAuthState(updateStatusReq);
    }
    @Operation(summary = "功能配置轮询状态")
    @PostMapping("/auth/limitRouter")
    CommonResult<Void> updateLimitRouter(@Validated @RequestBody UpdateMerchantAccessAuthStateReq updateStatusReq) {
        return merchantAccessAppService.updateAccessAuthLimitRouter(updateStatusReq);
    }


    @Operation(summary = "功能配置列表分页")
    @GetMapping("/auth/page")
    CommonResult<MerchantAccessAuthResp> queryPage(@Validated MerchantAccessAuthPageReq merchantAccessAuthPageReq) {
        return merchantAccessAppService.merchantAccessAuthPage(merchantAccessAuthPageReq);

    }

    @Operation(summary = "功能配置商户列表分页")
    @GetMapping("/auth/sn/page")
    CommonResult<PageResult<MerchantAccessAuthDetailResp>> querySnPage(@Validated MerchantAccessSnAuthPageReq merchantAccessAuthPageReq) {
        return merchantAccessAppService.merchantAccessSnAuthPage(merchantAccessAuthPageReq);

    }

    @Operation(summary = "删除AUT")
    @PostMapping("/delAuth")
    CommonResult<Void> delAuth(@Validated @RequestBody DeleteIdReq deleteIdReq) {
        return merchantAccessAppService.delAuth(deleteIdReq.getId());
    }
    @Operation(summary = "提交微信配置")
    @PostMapping("/wechatConfig")
    CommonResult<Void> submitWechatConfig(@Validated @RequestBody MerchantWechatConfigDto merchantAccessChannelReq) {
        return merchantAccessAppService.submitWechatConfig(merchantAccessChannelReq);
    }


    @Operation(summary = "商户进件列表")
    @GetMapping("")
    CommonResult<PageResult<MerchantAccessInfoListResp>> merchantAccessInfo(MerchantAccessPageReq merchantAccessInfoPageReq) {
        MerchantAccessInfoPageQueryDto merchantAccessInfoPageQueryDto = BeanUtil.copyProperties(merchantAccessInfoPageReq, MerchantAccessInfoPageQueryDto.class);
        processQueryDate(merchantAccessInfoPageReq, merchantAccessInfoPageQueryDto);
        merchantAccessInfoPageQueryDto.setLikeSn(merchantAccessInfoPageQueryDto.getSn());
        merchantAccessInfoPageQueryDto.setSn(null);
        PageResult<MerchantAccessInfoPageDto> page = merchantAccessService.queryPage(merchantAccessInfoPageQueryDto);
        List<MerchantAccessInfoPageDto> list = page.getList();
        if (CollectionUtils.isEmpty(list)) {
            return buildPageResult(page, Collections.emptyList());
        }
        List<MerchantAccessInfoListResp> merchantAccessInfoListResps = MerchantAccessDoToResp.INSTANCE.doToRespList(list);
        processProvideList(merchantAccessInfoListResps);
        return buildPageResult(page, merchantAccessInfoListResps);
    }

    @Operation(summary = "AT重新报备")
    @PostMapping("/access/split")
    CommonResult<MerchantChannelSplitReq> accessSplit(@Validated @RequestBody MerchantChannelSplitReq merchantChannelSplitReq) {
        return merchantAccessAppService.easySplit(merchantChannelSplitReq);
    }

    @Operation(summary = "模板导出")
    @PostMapping("/auth/template/export")
    public CommonResult<String> exportExcel(@RequestBody MerchantAuthExportReq merchantAuthExportReq, HttpServletResponse response) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        EasyExcel.write(outputStream, MerchantAuthExportInfo.class)
                .registerWriteHandler(DownloadExcelServiceImpl.getHorizontalCellStyleStrategy())
                .sheet("模板导出")
                .doWrite(CollUtil.newArrayList());
        CommonResult<String> commonResult = uploadService.upload(outputStream.toByteArray(), CommonEnum.OssEnum.EXCEL);
        return commonResult;

    }


    @Operation(summary = "模板导入")
    @PostMapping("/auth/template/import")
    CommonResult<Void> importExcel(@RequestParam("accessId") Long accessId,@RequestParam("file") MultipartFile excel) {
        return merchantAccessAppService.importExcel(accessId,excel);
    }

    @Operation(summary = "认证修改")
    @PostMapping("/auth/update")
    CommonResult<Void> authUpdate(@RequestBody MerchantAccessAuthDO merchantAccessAuthDO) {
        return merchantAccessAppService.updateAccessAuth(merchantAccessAuthDO);
    }
}
